﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace 文件内容队列读写
{
    /// <summary>
    /// 终端数据批量写入处理逻辑
    /// </summary>
    public class TerminalDbDataLogic
    {
        //1.1个线程写数据
        //2.一个线程不停的提交事务,打开新事务
        //3.一个线程不停的读取数据,删除数据.
        //4.同时批量操作100个数据库看看效果
        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            //批量数据写入
            Task.Factory.StartNew(() => { while (!暂停运行) { Write(); } });
            //事务提交,打开线程
            Task.Factory.StartNew(() => { while (!暂停运行) { Commit(); } });
            //数据读取删除线程
            Task.Factory.StartNew(() => { while (!暂停运行) { Del(); } });
        }

        private bool _暂停运行 = false;
        /// <summary>
        /// 暂停运行,并且将所有的数据都进行提交
        /// </summary>
        public bool 暂停运行
        {
            get { return _暂停运行; }
            set
            {
                _暂停运行 = value;
                var arr = collection.ToArray();
                //暂停运行
                if (value == false)
                {

                    //使用多线程
                    System.Threading.Tasks.Parallel.For(0, collection.Count, (i) =>
                    {
                        var item = arr[i];
                        //开始数据库
                        item.Value.BeginDB();
                    });
                    Init();
                }
                else {
                    //使用多线程
                    System.Threading.Tasks.Parallel.For(0, collection.Count, (i) =>
                    {
                        var item = arr[i];
                        //开始数据库
                        item.Value.Commit(false);
                    });
                }
            }
        }

        #region 写入删除数据
        /// <summary>
        /// 向数据库写数据
        /// </summary>
        protected void Write()
        {
            bool cansleep = true;
            foreach (var item in collection.ToArray())
            {
                string sql;
                List<string> sqls = new List<string>();
                //获取数据
                while (item.Value.WriteQueue.TryDequeue(out sql))
                {
                    if (string.IsNullOrEmpty(sql))
                    {
                        continue;
                    }
                    sqls.Add(sql);
                }
                if (sqls.Count > 0)
                {
                    item.Value.BatchExecuteInsert(sqls);
                }
                sqls.Clear();
                cansleep = false;
            }
            //如果全部没有数据则线程休眠
            if (cansleep)
            {
                System.Threading.Thread.Sleep(1000);
            }
        }
        /// <summary>
        /// 删除数据队列
        /// </summary>
        protected void Del()
        {
            bool cansleep = true;
            foreach (var item in collection.ToArray())
            {

                string sql;
                List<string> sqls = new List<string>();
                //获取数据
                while (item.Value.DelQueue.TryDequeue(out sql))
                {
                    if (string.IsNullOrEmpty(sql))
                    {
                        continue;
                    }
                    sqls.Add(sql);
                }
                if (sqls.Count > 0)
                {
                    item.Value.BatchExecuteInsert(sqls);
                }

                sqls.Clear();
                cansleep = false;
            }
            //如果全部没有数据则线程休眠
            if (cansleep)
            {
                System.Threading.Thread.Sleep(1000);
            }
        }
        #endregion

        #region 读取数据List对像缓存
        Dictionary<int, DataColumn> columnDics;
        Dictionary<int, Action<文件内容队列读写.DataQueue.TerminalData, IDataReader>> actionDics;
        Dictionary<string, System.Reflection.PropertyInfo> perDic;
        #endregion
        /// <summary>
        /// 读取数据产生需要发送的队列
        /// </summary>
        public void Reader()
        {
            bool cansleep = true;
            foreach (var item in collection.ToArray())
            {
                //一次读取200条数据
                if (item.Value.ReaderQueue.Count > 0) { return; }

                long limitMaxReadid = (item.Value.MaxReaderID + item.Value.ReadLimitNumber);
                string sql = "select  * from TerminalData  where id >" + item.Value.MaxReaderID + " and id<=" + limitMaxReadid + " order by id asc";
                System.Data.SQLite.SQLiteDataReader reader = null;
                List<DataQueue.TerminalData> list = new List<DataQueue.TerminalData>();
                try
                {
                    reader = item.Value.GetReader(sql);
                    if (reader != null)
                    {
                        list = reader.ReaderToList<DataQueue.TerminalData>(ref columnDics, ref actionDics, ref perDic);
                    }
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
                if (list.Count > 0)
                {
                    cansleep = false;
                    //获取最大ID
                    item.Value.MaxReaderID = list[list.Count - 1].ID;
                    //将数据写入到写队列中
                    list.ForEach(o =>
                    {
                        item.Value.ReaderQueue.Enqueue(o);
                    });
                }
            }
            //如果全部没有数据则线程休眠
            if (cansleep)
            {
                System.Threading.Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 消耗时间
        /// </summary>
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        //提交
        protected void Commit()
        {
            sw.Restart();
            bool cansleep = true;

            var arr = collection.ToArray();
            //使用多线程
            System.Threading.Tasks.Parallel.For(0, collection.Count, (i) =>
            {
                var item = arr[i];

                if (!暂停运行)
                {
                    item.Value.Commit();
                    item.Value.BeginDB();
                }
                else
                {
                    //表示数据库可操作
                    if (!item.Value.CanOperation)
                    {
                        item.Value.Commit(false);
                    }
                }

            });

            sw.Stop();
            Console.WriteLine("--提交:{0}个记录文件,用时{1}毫秒", collection.Count, sw.ElapsedMilliseconds);

            //如果全部没有数据则线程休眠
            if (cansleep)
            {
                System.Threading.Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 所有终端数据库集合
        /// </summary>
        private System.Collections.Concurrent.ConcurrentDictionary<string, TerminalDbData> collection = new System.Collections.Concurrent.ConcurrentDictionary<string, TerminalDbData>();
        /// <summary>
        /// 所有终端数据库集合
        /// </summary>
        public System.Collections.Concurrent.ConcurrentDictionary<string, TerminalDbData> Collection
        {
            get { return collection; }
        }


    }
}
